package com.retail.shopping.server.service.impl;

import com.retail.shopping.common.domain.ShoppingCart;
import com.retail.shopping.common.domain.response.CartListResponse;
import com.retail.shopping.server.service.IShoppingCartMiddenService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 功能描述:
 *
 * @version: java version 1.8
 * @author: liguangyao
 * @date: 2024-03-08 下午 2:40
 */
@Service
public class ShopCartBatchService {

    //@Resource 和autowired是一样的用来声明对象但是autowred是spring提供的在spring中最好还是用autowired
    @Autowired
    private IShoppingCartMiddenService iShoppingCartMiddenService;

    /**
     * 最大的请求数量
     */
    public static Integer MAX_TASK_NUM=100;

    @Data
    public class CartMergeRequest {
        //唯一健
        String requestId;
        //用户编号
        Integer userId;
        //购物车集合
        CompletableFuture<Map<String, List<Map<String, Object>>>> completableFuture;
    }


    //创建一个队列
    public final Queue<CartMergeRequest> queue=new LinkedBlockingQueue<> ();

    //依赖执行完成之后完成一些初始化操作
    //可以在方法中完成一些必要的初始化
    @PostConstruct
    public void init(){
        //定义一个 可定时的线程池
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool (1);
        //调用线程池
        scheduledExecutorService.scheduleAtFixedRate (()->{
            //获取队列中的请求数量
            int size = queue.size ();
            //判断线程数量是否足够
            if(size==0){
                //没有线程任务直接进行返回
                return;
            }
            ArrayList<CartMergeRequest> list = new ArrayList<> ();
            //输出提示
            System.out.println ("========================合并了["+size+"]个请求============================");

            for (int i = 0; i < size; i++) {
                //超过最大线程数九等待下次执行
                if(i<MAX_TASK_NUM){
                    list.add (queue.poll ());//poll()做的是从首个元素开始取出并移除
                }
            }
            //拿到我们需要的数据
            ArrayList<CartMergeRequest> cartReqs = new ArrayList<> ();
            for (CartMergeRequest cartMergeRequest : list) {
                cartReqs.add (cartMergeRequest);
            }
            //将参数传入到service处理这里是本地服务也是可以吧Service
            Map<Integer, Map<ShoppingCart, List<CartListResponse>>> response = iShoppingCartMiddenService.selectCartMergerBathchList(cartReqs);
            //将查询到的数据返回到各自的请求中
            for (CartMergeRequest request : list) {

                Map<ShoppingCart, List<CartListResponse>> cartListMap = response.get(request.getUserId());

                // 使用Java 8 Stream API进行转换
                List<Map<String, Object>> dataList = cartListMap.entrySet().stream()
                        .flatMap(entry -> entry.getValue().stream()
                                .map(cartListResponse -> {
                                    Map<String, Object> dataMap = new LinkedHashMap<> ();
                                    dataMap.put("middenId", cartListResponse.getMiddenId());
                                    dataMap.put("cartId", cartListResponse.getCartId());
                                    dataMap.put("skuId", cartListResponse.getSkuId());
                                    dataMap.put("skuNum", cartListResponse.getSkuNum());
                                    dataMap.put("inputPrice", cartListResponse.getInputPrice());
                                    dataMap.put("skuTotalPrice", cartListResponse.getSkuTotalPrice());
                                    dataMap.put("cartStatus", cartListResponse.getCartStatus());
                                    dataMap.put("skuName", cartListResponse.getSkuName());
                                    dataMap.put("saleStatus", cartListResponse.getSaleStatus());
                                    dataMap.put("skuImg", cartListResponse.getSkuImg());
                                    dataMap.put("skuDescription", cartListResponse.getSkuDescription());
                                    dataMap.put("productCount", cartListResponse.getProductCount());
                                    return dataMap;
                                }))
                        .collect(Collectors.toList());

                Map<String, List<Map<String, Object>>> result = Collections.singletonMap("data", dataList);

                request.completableFuture.complete (result);

            }

        },100,10, TimeUnit.MILLISECONDS);

    }

    public Map<String, List<Map<String, Object>>> selectShoppingCartMergeMiddenList(Integer userId) {
        CartMergeRequest request = new CartMergeRequest ();
        request.requestId= UUID.randomUUID ().toString ().replace ("-","");
        request.userId=userId;
        CompletableFuture<Map<String, List<Map<String, Object>>>> future = new CompletableFuture<> ();
        request.completableFuture=future;
        queue.offer (request);
        try {
            return future.get ();
        } catch (InterruptedException e) {
            e.getStackTrace ();
        } catch (ExecutionException e) {
            e.getStackTrace ();
        }
        return null;
    }
}

